/**
 * @func fetch拦截器
 */

import qs from 'qs';
import service from './service';

let controllers = [];

const request = function(id, options = {}){

    const controller = new AbortController();
    const {signal} = controller;
    const rule = service[id];

    if(!rule){
        return
    }

    controllers.push(controller)

    const temp = rule.split(':');
    let url = temp[0], _method = temp[1] || 'get';

    if(!options.method && _method){
        options.method = _method
    }

    const {dataType, method} = options;
    const headers = {};
    const isGet = method.toLowerCase() === 'get';

    let data = options.body || '';

    switch(dataType){
        case 'json':
            headers['Content-Type'] = 'application/json'
            break
        default:
            headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
    }

    options.headers = {...options.headers, ...headers}

    if(typeof data === 'object'){
        switch(dataType){
            case 'json':
                data = JSON.stringify(data)
                break
            default:
                data = qs.stringify(data)
        }
    }

    // a/b => /a/b
    if(!/^(((https?:)?\/\/)|\/)/.test(url)){
        url = '/' + url
    }

    if(/^\//.test(url)){
        url = localStorage.getItem('domain').replace(/\/$/, '') + url
    }

    // a/b => a/b.do
    if(!/((\.\w+)|\/)$/.test(url)){
        url += '.do'
    }

    //no cache
    url += '?_=' + new Date().getTime()

    if(isGet){
        if(data){
            url += '&' + data
            delete options.body
        }
    }
    else{
        options.body = data
    }

    //请求时携带cookie，不然后台会做登录拦截
    if(!options.credentials){
        options.credentials = 'same-origin'
    }

    options.signal = signal

    return fetch(url, options)
                .then(res => {
                    const {status} = res;
                    if(status === 200){
                        let json;
                        if(res.headers.get('Content-Type').indexOf('image') === 0){
                            return res.blob()
                        }
                        else if(res.url.indexOf('tologin.do') !== -1){
                            json = {
                                status:308,
                                message:'请重新登录'
                            }
                        }
                        else{
                            json = res.json()
                        }
                        //登录失效拦截
                        if(json.status === 308){
                            request.abort()
                            location.hash = '/login'
                        }
                        return json
                    }
                    return {
                        result:'error',
                        message:status.toString()
                    }
                }).catch(err => {
                    
                })
}

;['get', 'post'].forEach(method => {
    request[method] = function(url, data, dataType){
        return request(url, {
            method,
            dataType,
            body:data,
        })
    }
})

request.abort = function(){
    //终止所有请求
    controllers.forEach(v=>{
        v.abort()
    })
    controllers = []
}

export default request